﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace IESN
{
    public class ControlHelper
    {
        #region 清除指定容器中控件的值

        /// <summary>          
        /// 清除容器里面某些控件的值      
        /// </summary>          
        /// <param name="containerControl">容器类控件</param>          
        public static void ClearControl(Control containerControl)
        {
            foreach(Control eachCtrl in containerControl.Controls)
            {
                // 如果是容器类控件，递归调用                  
                if (eachCtrl.HasChildren)
                {
                    ClearControl(eachCtrl);
                }
                else
                {
                    if (eachCtrl is TextBox)
                        eachCtrl.Text = "";

                    if (eachCtrl is ComboBox)
                        eachCtrl.Text = "";

                    if (eachCtrl is CheckBox)
                        ((CheckBox)eachCtrl).Checked = false;

                    if (eachCtrl is RadioButton)
                        ((RadioButton)eachCtrl).Checked = false;

                    if (eachCtrl is PictureBox)
                        ((PictureBox)eachCtrl).Image = null;

                    if (eachCtrl is TreeView)
                        CheckAllChildNodes(((TreeView)eachCtrl).Nodes[0], false);
                }
            }
        }

        /// <summary>
        /// 设置树节点CheckBox
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="IsChecked"></param>
        private static void CheckAllChildNodes(TreeNode treeNode, bool IsChecked)
        {
            foreach (TreeNode eachNode in treeNode.Nodes)
            {
                eachNode.Checked = IsChecked;

                if (eachNode.Nodes.Count > 0)
                {
                    CheckAllChildNodes(eachNode, IsChecked);
                }
            }
        }

        #endregion

        #region 组装增删改语句

        /// <summary>
        /// 构造插入的sql语句
        /// </summary>
        /// <param name="table"></param>
        /// <param name="moduleObj"></param>
        /// <returns></returns>
        public static string ConvertToInsertSQL(string table, object moduleObj)
        {
            string strReturn = string.Empty;

            string strProperty = " (";
            string strValue = " Values (";

            strReturn = "Insert Into " + table;

            foreach (System.Reflection.PropertyInfo p in moduleObj.GetType().GetProperties())
            {
                if (p.Name == "TableName")
                    continue;

                strProperty += "" + p.Name + ",";

                if (p.PropertyType == typeof(System.Decimal) || p.PropertyType == typeof(System.Int32))
                {
                    strValue += p.GetValue(moduleObj, null) + ",";
                }
                else
                {
                    strValue += "'" + p.GetValue(moduleObj, null) + "',";
                }
            }

            strProperty = strProperty.Substring(0, strProperty.Length - 1) + ")";
            strValue = strValue.Substring(0, strValue.Length - 1) + ")";

            strReturn += strProperty + " " + strValue;

            return strReturn;
        }

        /// <summary>
        /// 构造更新sql语句
        /// </summary>
        /// <param name="table"></param>
        /// <param name="moduleObj"></param>
        /// <returns></returns>
        public static string ConvertToUpdateSQL(string table, object moduleObj)
        {
            string strReturn = "Update " + table;
            string strSetValue = " Set ";
            string strWhere = " Where ";

            foreach (System.Reflection.PropertyInfo p in moduleObj.GetType().GetProperties())
            {
                if (p.Name == "TableName")
                    continue;

                if (p.Name == "ID")
                    strWhere += " ID ='" + p.GetValue(moduleObj, null) + "'";

                strSetValue += "" + p.Name + "=";

                if (p.PropertyType == typeof(System.Decimal) || p.PropertyType == typeof(System.Int32))
                {
                    strSetValue += p.GetValue(moduleObj, null) + ",";
                }
                else
                {
                    strSetValue += "'" + p.GetValue(moduleObj, null) + "',";
                }
            }

            strSetValue = strSetValue.Substring(0, strSetValue.Length - 1);

            strReturn += strSetValue + strWhere;
            return strReturn;
        }

        /// <summary>
        /// 构造删除的SQL语句
        /// </summary>
        /// <param name="table"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static string ConvertToDeleteSQL(string table, string id)
        {
            string strReturn = string.Empty;

            strReturn = "Delete From " + table + " Where ID='" + id + "'";

            return strReturn;
        }

        #endregion
        
        #region 获取窗体控件值

        /// <summary>
        /// 将各控件的值赋给对象的对应属性
        /// </summary>
        /// <param name="control">容器</param>
        /// <param name="moduleObj">需赋值的对象</param>
        /// <param name="isComboBoxSelectValue">是否为SelectValue</param>
        public static void SetControlValueToObject(Control control, object moduleObj, bool isComboBoxSelectValue)
        {
            if (moduleObj == null || control == null)
                return;

            Type objType = moduleObj.GetType();

            foreach (Control eachCtrl in control.Controls)
            {
                // 如果是容器类控件，递归调用自己                  
                if (eachCtrl.HasChildren)
                {
                    SetControlValueToObject(eachCtrl, moduleObj, isComboBoxSelectValue);
                }
                else
                {
                    #region 取控件名字和对象属性名

                    string propertyName = GetPropertyNameByControl(eachCtrl);

                    //如果控件名称为空，或者对象没有对应控件名称的属性,则遍历下一个
                    if (propertyName == string.Empty || objType.GetProperty(propertyName) == null)
                        continue;

                    PropertyInfo propertyInfo = objType.GetProperty(propertyName);
                    if (!propertyInfo.CanWrite)
                    {
                        continue;
                    }

                    #endregion

                    #region 取控件的值

                    object objTemp = GetControlValue(eachCtrl, propertyInfo, isComboBoxSelectValue);

                    object objActual = null;

                    if (objTemp == null)
                        continue;

                    if(objTemp.ToString()==string.Empty &&(propertyInfo.PropertyType == typeof(System.Double)||propertyInfo.PropertyType == typeof(System.Decimal) || propertyInfo.PropertyType == typeof(System.Int32)))
                    {
                        objTemp = 0;
                    }

                    //if (objTemp == null ||
                    //    ((objTemp.ToString() == string.Empty)
                    //    && (propertyInfo.PropertyType == typeof(System.Decimal) || propertyInfo.PropertyType == typeof(System.Int32))
                    //    ))
                    //{
                    //    continue;
                    //}

                    try
                    {
                        if (!propertyInfo.PropertyType.IsGenericType)
                        {
                            objActual = Convert.ChangeType(objTemp, propertyInfo.PropertyType);
                        }
                        else
                        {
                            Type genericTypeDefinition = propertyInfo.PropertyType.GetGenericTypeDefinition();
                            if (genericTypeDefinition == typeof(Nullable<>))
                            {
                                if (objTemp != null && objTemp.ToString() != string.Empty)
                                    objActual = Convert.ChangeType(objTemp, Nullable.GetUnderlyingType(propertyInfo.PropertyType));
                            }
                        }
                    }
                    catch (InvalidCastException ex)
                    {
                        throw ex;
                    }

                    //赋值
                    if (objActual != null)
                    {
                        propertyInfo.SetValue(moduleObj, objActual, null);
                    }

                    #endregion
                }
            }
        }

        /// <summary>
        /// 获取控件的名称得到属性名
        /// </summary>
        /// <param name="eachControl"></param>
        /// <param name="isContainCKB"></param>
        /// <returns></returns>
        private static string GetPropertyNameByControl(Control eachControl)
        {
            string propertyName = string.Empty;

            if (
                   ((eachControl is TextBox) && eachControl.Name.StartsWith("txt"))
                || ((eachControl is ComboBox) && eachControl.Name.StartsWith("cbb"))
                || ((eachControl is DateTimePicker) && eachControl.Name.StartsWith("dtp"))
                || ((eachControl is NumericUpDown) && eachControl.Name.StartsWith("nud"))
                || ((eachControl is CheckBox) && eachControl.Name.StartsWith("ckb"))
                )
            {
                propertyName = eachControl.Name.Trim().Substring(3, eachControl.Name.Length - 3);
            }
            return propertyName;
        }

        /// <summary>
        /// 取控件值
        /// </summary>
        /// <param name="eachControl"></param>
        /// <param name="propertyInfo"></param>
        /// <param name="isComboBoxSelectValue"></param>
        /// <returns></returns>
        private static object GetControlValue(Control eachControl, PropertyInfo propertyInfo, bool isComboBoxSelectValue)
        {
            object objTemp = null;

            if (eachControl is TextBox)
            {
                objTemp = (eachControl as TextBox).Text.Trim();
            }
            else if (eachControl is ComboBox)
            {
                if (isComboBoxSelectValue)
                {
                    objTemp = (eachControl as ComboBox).SelectedValue;
                }
                else
                {
                    objTemp = (eachControl as ComboBox).Text;
                }
            }
            else if (eachControl is NumericUpDown)
            {
                objTemp = (eachControl as NumericUpDown).Value;
            }
            else if (eachControl is CheckBox)
            {
                if (propertyInfo.PropertyType == typeof(System.String))
                {
                    objTemp = ConvertToString((eachControl as CheckBox).Checked);
                }
                else
                {
                    objTemp = ConvertToInt((eachControl as CheckBox).Checked);
                }
            }
            else if (eachControl is DateTimePicker)
            {
                objTemp = (eachControl as DateTimePicker).Text;
            }

            return objTemp;
        }

        #endregion

        #region 设置值到界面

        /// <summary>
        /// 为对象给相对应容器上子控件赋值
        /// </summary>
        /// <param name="moduleObj">取值对象</param>
        /// <param name="control">容器</param>
        /// <param name="isComboBoxSelectValue">是否获取SelectValue</param>
        public static void SetObjectValueToControl(object moduleObj, Control control, bool isComboBoxSelectValue=true)
        {

            if (moduleObj == null || control == null)
            {
                return;
            }

            Type type = moduleObj.GetType();

            foreach(Control eachCtrl in control.Controls)
            {
                // 如果是容器类控件，递归调用自己                  
                if (eachCtrl.HasChildren)
                {
                    SetObjectValueToControl(moduleObj, eachCtrl, isComboBoxSelectValue);
                }
                else
                {
                    string propertyname = string.Empty;

                    if (((eachCtrl is TextBox) && eachCtrl.Name.StartsWith("txt"))
                    || ((eachCtrl is ComboBox) && eachCtrl.Name.StartsWith("cbb"))
                    || ((eachCtrl is DateTimePicker) && eachCtrl.Name.StartsWith("dtp"))
                    || ((eachCtrl is NumericUpDown) && eachCtrl.Name.StartsWith("nud"))
                    || ((eachCtrl is CheckBox) && eachCtrl.Name.StartsWith("ckb")))
                    {
                        propertyname = eachCtrl.Name.Trim().Substring(3, eachCtrl.Name.Length - 3);
                    }
                    else
                    {
                        continue;
                    }

                    PropertyInfo property = type.GetProperty(propertyname);

                    object objActual = null;

                    if (property != null)
                    {
                        objActual = property.GetValue(moduleObj, null);
                    }
                    else
                    {
                        continue;
                    }

                    ClearControlValue(eachCtrl);

                    if (objActual != null)
                    {
                        if (eachCtrl is TextBox)
                        {
                            (eachCtrl as TextBox).Text = objActual.ToString();
                        }
                        else if (eachCtrl is ComboBox)
                        {
                            if (isComboBoxSelectValue)
                            {
                                (eachCtrl as ComboBox).SelectedValue = '0';
                                (eachCtrl as ComboBox).SelectedValue = objActual.ToString();
                            }
                            else
                            {
                                (eachCtrl as ComboBox).Text = objActual.ToString();
                            }
                        }

                        else if (eachCtrl is NumericUpDown)
                        {
                            (eachCtrl as NumericUpDown).Value = Convert.ToDecimal(objActual);
                        }
                        else if (eachCtrl is DateTimePicker)
                        {
                            DateTime dtTemp;

                            DateTime.TryParse(objActual.ToString(), out dtTemp);

                            if (DateTimePicker.MaximumDateTime > dtTemp && DateTimePicker.MinimumDateTime < dtTemp)
                            {
                                (eachCtrl as DateTimePicker).Value = dtTemp;
                            }
                        }

                        else if (eachCtrl is CheckBox)
                        {
                            if (property.PropertyType == typeof(System.String))
                            {
                                //(control.Controls[index] as CheckBox).Checked = ConvertToBoolean(objActual.ToString());
                            }
                            else
                            {
                                //(control.Controls[index] as CheckBox).Checked = ConvertToBoolean(Convert.ToInt32(objActual));
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 清空控件的值
        /// </summary>
        /// <param name="control"></param>
        private static void ClearControlValue(Control control)
        {
            if (control is TextBox)
            {
                (control as TextBox).Text = string.Empty;
            }

            else if (control is ComboBox)
            {
                (control as ComboBox).Text = string.Empty;
            }

            else if (control is NumericUpDown)
            {
                (control as NumericUpDown).Value = Convert.ToDecimal(0);
            }
            //else if (control is DateTimePicker)
            //{
            //    DateTime dtTemp;

            //    DateTime.TryParse(objActual.ToString(), out dtTemp);

            //    if (DateTimePicker.MaximumDateTime > dtTemp && DateTimePicker.MinimumDateTime < dtTemp)
            //    {
            //        (control.Controls[index] as DateTimePicker).Value = dtTemp;
            //    }yg
            //}

            else if (control is CheckBox)
            {
                (control as CheckBox).Checked = false;
            }
        }

        #endregion

        #region 常用数值转换

        /// <summary>
        /// 布尔值转化为整数值
        /// </summary>
        /// <param name="value">布尔值</param>
        /// <returns>字符串</returns>
        private static string ConvertToString(bool value, CovertBooleanType type)
        {
            if (value)
            {
                if (type == CovertBooleanType.Number)
                {
                    return "1";
                }
                else if (type == CovertBooleanType.YesNo)
                {
                    return "Y";
                }
                else if (type == CovertBooleanType.是否)
                {
                    return "是";
                }
                else if (type == CovertBooleanType.真假)
                {
                    return "真";
                }
                else
                {
                    return "1";
                }
            }
            else
            {
                if (type == CovertBooleanType.Number)
                {
                    return "0";
                }
                else if (type == CovertBooleanType.YesNo)
                {
                    return "N";
                }
                else if (type == CovertBooleanType.是否)
                {
                    return "否";
                }
                else if (type == CovertBooleanType.真假)
                {
                    return "假";
                }
                else
                {
                    return "0";
                }
            }
        }

        /// <summary>
        /// 布尔值转化为字符串
        /// </summary>
        /// <param name="value">布尔值</param>
        /// <returns>字符串</returns>
        private static string ConvertToString(bool value)
        {
            return ConvertToString(value, CovertBooleanType.Number);
        }

        /// <summary>
        /// 布尔值转化为整数值
        /// </summary>
        /// <param name="value">布尔值</param>
        /// <returns>整数值</returns>
        private static int ConvertToInt(bool value)
        {
            if (value)
                return 1;
            else
                return 0;
        }

        /// <summary>
        /// 真假类型
        /// </summary>
        private enum CovertBooleanType
        {
            Number = 1,
            YesNo = 2,
            是否 = 3,
            真假 = 4,
        }

        #endregion

        /// <summary>
        /// 控件可用性设置
        /// </summary>
        /// <param name="containerControl"></param>
        /// <param name="isEnabled"></param>
        public static void SetControlEnable(Control containerControl, bool isEnabled)
        {
            foreach (Control eachCtrl in containerControl.Controls)
            {
                // 如果是容器类控件，递归调用                  
                if (eachCtrl.HasChildren)
                {
                    SetControlEnable(eachCtrl, isEnabled);
                }
                else
                {
                    if (eachCtrl is TextBox || eachCtrl is ComboBox
                     || eachCtrl is CheckBox || eachCtrl is RadioButton
                     || eachCtrl is DateTimePicker || eachCtrl is ToolStrip
                     || eachCtrl is Button
                        )
                        eachCtrl.Enabled = isEnabled;
                    else
                        eachCtrl.Enabled = true;
                }
            }
        }

    }
}
